/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2025. All rights reserved.
 * Global Trust Authority is licensed under the Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *     http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
 * PURPOSE.
 * See the Mulan PSL v2 for more details.
 */

use std::future::Future;
use std::pin::Pin;
use std::sync::Arc;

use actix_web::web;
use sea_orm::DatabaseConnection;

use crate::entities::db_model::rv_db_model::Model as RvDbModel;
use crate::entities::inner_model::rv_model::RefValueModel;
use crate::entities::request_body::rv_del_req_body::RvDelReqBody;
use crate::entities::request_body::rv_update_req_body::RvUpdateReqBody;
use crate::error::ref_value_error::RefValueError;

/// Trait defining the interface for reference value operations
#[allow(async_fn_in_trait)]
pub trait RefValueTrait {
    /// Adds a new reference value to the database
    async fn add(
        &self,
        conn: web::Data<Arc<DatabaseConnection>>,
        rv_model: &RefValueModel,
    ) -> Result<(), RefValueError>;

    /// Updates an existing reference value in the database
    async fn update(
        &self,
        conn: web::Data<Arc<DatabaseConnection>>,
        user_id: &str,
        update_req_body: &RvUpdateReqBody,
    ) -> Result<RvDbModel, RefValueError>;

    /// Deletes a reference value from the database
    async fn delete(
        &self,
        conn: web::Data<Arc<DatabaseConnection>>,
        user_id: &str,
        del_type: &str,
        del_req_body: &RvDelReqBody,
    ) -> Result<(), RefValueError>;

    /// Verifies measurements against reference values
    fn verify<'a>(
        &'a self,
        measurements: &'a Vec<String>,
        user_id: &'a str,
        attester_type: &'a str,
    ) -> Pin<Box<dyn Future<Output = Result<Vec<String>, String>> + Send + 'a>>;
}
